<?php

namespace app\api\controller;

use app\common\controller\Api;

use app\common\model\Contracts as ContractsModel;
use app\common\model\Customer as CustomerModel;
use app\common\model\PaymentPlan as PaymentPlanModel;
use app\common\model\User;
use PhpOffice\PhpSpreadsheet\IOFactory;
use think\Db;
use think\Request;
use app\common\model\PaymentRecord as PaymentrecordModel;
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
use app\common\service\UserPermissionService;
use think\Response;
/**
 * 首页接口
 */
class Paymentrecord extends Api
{
    protected $noNeedLogin = [];
    protected $noNeedRight = ['*'];
    public function getStatistics()
    {
        $paymentRecord = new \app\common\model\PaymentRecord();
        $userId = $this->auth->id;

        // 1. 全部
        $whereAll = [];
        $whereAll['is_delete'] = 0;

        //数据权限
        $userPermissionService = new UserPermissionService();
        $staffids=$userPermissionService->getUsersByPermission($this->auth->id);
        $whereAll['staff_id']=['in',$staffids];


        $totalAll = $paymentRecord->where($whereAll)->count();

        // 2. 我负责的
        $whereMine = $whereAll;
        $whereMine['staff_id'] = $userId;
        $totalMine = $paymentRecord->where($whereMine)->count();

        // 3. 下属负责的
        $staffids = Db::name('user')->where('leader_id', $userId)->column('id');
        $whereSub = $whereAll;
        if ($staffids) {
            $whereSub['staff_id'] = ['in', $staffids];
            $totalSub = $paymentRecord->where($whereSub)->count();
        } else {
            $totalSub = 0;
        }

        $data = [
            ['type' => 1, 'title' => '全部', 'value' => $totalAll],
            ['type' => 2, 'title' => '我负责的', 'value' => $totalMine],
            ['type' => 3, 'title' => '下属负责的', 'value' => $totalSub],
        ];

        $this->success('success', $data);
    }


    /**
     * 构建查询条件
     * @param array $params 查询参数
     * @param int $type 查询类型
     * @return array
     */
    private function buildWhere($params, $type)
    {
        $where = [];
        $where['a.is_delete'] = 0;
        

        //数据权限
        $userPermissionService = new UserPermissionService();
        $staffids=$userPermissionService->getUsersByPermission($this->auth->id);
        $where['a.staff_id']=['in',$staffids];


        // 搜索关键词
        $searchKey = isset($params['searchKey']) ? $params['searchKey'] : '';
        if ($searchKey) {
            $where['c.customerName|c.phone|c.uidipin'] = ['like', "%{$searchKey}%"];
        }

        // 回款日期筛选
        if (isset($params['dateStart']) && !empty($params['dateStart'])) {
            $dateStart = $params['dateStart'];
            $dateEnd = isset($params['dateEnd']) && !empty($params['dateEnd']) ? $params['dateEnd'] : $dateStart;
            $where['a.date'] = ['between', [$dateStart, $dateEnd]];
        }

        // 回款方式筛选
        if (isset($params['method']) && !empty($params['method'])) {
            $where['a.method'] = $params['method'];
        }

        // 回款账户筛选
        if (isset($params['account_id']) && !empty($params['account_id'])) {
            $where['a.account_id'] = $params['account_id'];
        }
        // 负责人筛选
        if (isset($params['staff_id']) && !empty($params['staff_id'])) {
            $where['a.staff_id'] = $params['staff_id'];
        }
        // 创建人筛选
        if (isset($params['user_id']) && !empty($params['user_id'])) {
            $where['a.user_id'] = $params['user_id'];
        }
        
        // 
        if (isset($params['productName']) && !empty($params['productName'])) {
            $where['a.productName'] = $params['productName'];
        }

        if (isset($params['is_bill']) && !empty($params['is_bill'])) {
            $where['a.is_bill'] = $params['is_bill'];
        }
     

        // 登记日期筛选
        if (isset($params['register_dateStart']) && !empty($params['register_dateStart'])) {
            $registerDateStart = $params['register_dateStart'];
            $registerDateEnd = isset($params['register_dateEnd']) && !empty($params['register_dateEnd']) ? $params['register_dateEnd'] : $registerDateStart;
            $where['a.registrationDate'] = ['between', [$registerDateStart, $registerDateEnd]];
        }

        // 创建时间筛选
        if (isset($params['createtimeStart']) && !empty($params['createtimeStart'])) {
            $createtimeStart = $params['createtimeStart'];
            $createtimeEnd = isset($params['createtimeEnd']) && !empty($params['createtimeEnd']) ? $params['createtimeEnd'] : $createtimeStart;
            $where['a.createtime'] = ['between', [$createtimeStart, $createtimeEnd]];
        }

        // 负责律师筛选
        if (isset($params['lawyer']) && !empty($params['lawyer'])) {
            $where['a.lawyer'] = ['like', "%{$params['lawyer']}%"];
        }

        // 实际还款人筛选
        if (isset($params['payname']) && !empty($params['payname'])) {
            $where['a.payname'] = ['like', "%{$params['payname']}%"];
        }
        if (isset($params['bill_staff_id']) && !empty($params['bill_staff_id'])) {
            $where['a.bill_staff_id'] = $params['bill_staff_id'];
        }
        // 所属单号筛选
        if (isset($params['loanno']) && !empty($params['loanno'])) {
            $where['a.loanno'] = ['like', "%{$params['loanno']}%"];
        }

        // 分润人筛选（profit_id 存储为英文逗号分隔的字符串）
        if (isset($params['profit_id']) && $params['profit_id'] !== '' && $params['profit_id'] !== null) {
            $paymentids=Db::name('payment_profit')->where('profit_id',$params['profit_id'])->column('payment_id');
            $where['a.id'] = ['in', $paymentids];
        }

 
        
        
         if (isset($params['department_id']) && !empty($params['department_id'])) {
            // 获取这些部门的所有用户ID
            $userIds = $this->getDepartmentUserIds($params['department_id']);
            // 与数据权限的staffids取交集
            $where['a.staff_id'] = ['in', array_intersect($userIds, $staffids)];
        } 



        // 类型筛选
        switch ($type) {
            case 1: // 全部
                break;
            case 2: // 我负责的
                $where['a.staff_id'] = $this->auth->id;
                break;
            case 3: // 下属负责的
                $staffids = Db::name('user')->where('leader_id', $this->auth->id)->column('id');
                if ($staffids) {
                    $where['a.staff_id'] = ['in', $staffids];
                } else {
                    $where['a.staff_id'] = 0; // 不会有结果
                }
                break;
            default:
                break;
        }

        return $where;
    }

    public function getPaymentRecordList()
    {
        // 获取分页参数
        $page = $this->request->post('page', 1);
        $pageSize = $this->request->post('pageSize', 20);
        $type = $this->request->post('type', 1);
        $params = $this->request->post(); // 筛选条件
        $action = $this->request->post('action', 'list'); // 新增：action参数，list或export
        
        // 使用统一的buildWhere方法构建查询条件
        $where = $this->buildWhere($params, $type);
        
        // 如果是导出操作
        if ($action === 'export') {
            return $this->exportAsync($where, $params);
        }
        
        // 如果是删除操作
        if ($action === 'delete') {
            return $this->handleDelete($where, $params);
        }

        $list=Db::name('payment_record a')
            ->join('customer c', 'a.customer_id = c.id', 'LEFT')
            ->join('user u', 'a.staff_id = u.id', 'LEFT')
            ->join('user us', 'a.user_id = us.id', 'LEFT')
            ->join('contracts co', 'a.contract_id = co.id', 'LEFT')
            ->join('payment_plan p', 'a.plan_id = p.id', 'LEFT')
            ->join('account ac', 'a.account_id = ac.id', 'LEFT')
            ->join('user ub', 'a.bill_staff_id = ub.id', 'LEFT')
            ->field('a.*, c.id as customerID,c.customerName,c.productName, c.uidipin,u.id as staff_id,u.name as staffName,us.id as user_id,us.name as userName,co.id as contractId,co.contractName,p.period,ac.account_name,ub.name as bill_staff_name')
            ->where($where)
            ->order('a.id desc')
            ->page($page, $pageSize)
            ->select();

        $ids=Db::name('payment_record a')
            ->join('customer c', 'a.customer_id = c.id', 'LEFT')
            ->join('user u', 'a.staff_id = u.id', 'LEFT')
            ->join('user us', 'a.user_id = us.id', 'LEFT')
            ->join('contracts co', 'a.contract_id = co.id', 'LEFT')
            ->join('payment_plan p', 'a.plan_id = p.id', 'LEFT')
            ->join('account ac', 'a.account_id = ac.id', 'LEFT')
            ->join('user ub', 'a.bill_staff_id = ub.id', 'LEFT')
            ->field('a.*, c.id as customerID,c.customerName,c.productName, c.uidipin,u.id as staff_id,u.name as staffName,us.id as user_id,us.name as userName,co.id as contractId,co.contractName,p.period,ac.account_name,ub.name as bill_staff_name')
            ->where($where)
            ->column('a.id');

            $count=count($ids);
            $ids=implode(',',$ids);


        $total =Db::name('payment_record a')
            ->join('customer c', 'a.customer_id = c.id', 'LEFT')
            ->join('user u', 'a.staff_id = u.id', 'LEFT')
            ->join('user us', 'a.user_id = us.id', 'LEFT')
            ->join('contracts co', 'a.contract_id = co.id', 'LEFT')
            ->join('payment_plan p', 'a.plan_id = p.id', 'LEFT')
            ->join('account ac', 'a.account_id = ac.id', 'LEFT')
            ->field('a.*, c.id as customerID,c.customerName, c.uidipin,u.id as staff_id,u.name as staffName,us.id as user_id,us.name as userName,co.id as contractId,co.contractName,p.period')
            ->where($where)
            ->count();

        foreach ($list as $key=>$value){
            $customer=['id'=>$value['customerID'],'customerName'=>$value['customerName'],'uidipin'=>$value['uidipin']];
            $staff=['id'=>$value['staff_id'],'name'=>$value['staffName']];
            $contract=['id'=>$value['contractId'],'contractName'=>$value['contractName']];
            $plan=['id'=>$value['plan_id'],'period'=>$value['period']];
            $user=['id'=>$value['user_id'],'name'=>$value['userName']];
            $list[$key]['customer']=$customer;
            $list[$key]['staff']=$staff;
            $list[$key]['user']=$user;
            $list[$key]['contract']=$contract;
            $list[$key]['plan']=$plan;
        }

        $total_amount_find=Db::name('payment_record a')
            ->join('customer c', 'a.customer_id = c.id', 'LEFT')
            ->join('user u', 'a.staff_id = u.id', 'LEFT')
            ->join('contracts co', 'a.contract_id = co.id', 'LEFT')
            ->join('payment_plan p', 'a.plan_id = p.id', 'LEFT')
            ->where($where)->field('sum(a.amount) as total')
            ->find();
        $total_amount=$total_amount_find['total']?$total_amount_find['total']:0;

        // 为图片URL添加域名前缀
        $request = Request::instance();
        $domain = $request->domain();
        foreach ($list as $k=>$v){
            if (!empty($v['image']) && is_string($v['image'])) {
                $certificate= json_decode($v['image'], true);
                foreach ($certificate as $key=>$value){
                    $certificate[$key]=$domain.$value;
                }
                $list[$k]['image'] = $certificate;
            }
            if(!empty($v['profitids'])){
                $profitids = explode(',', $v['profitids']);
                $profitnames = Db::name('user')->where('id', 'in', $profitids)->column('name');
                $list[$k]['profitnames'] = implode(',', $profitnames);
            }
        }
        

        $this->success('请求成功', ['list' => $list, 'total' => $total,'total_amount'=>$total_amount,'idlist'=>$ids]);
    }

    /**
     * 异步导出（提交任务后立即结束响应，后台继续处理）
     */
    public function exportAsync($where, $params)
    {
        // 生成导出任务ID
        $taskId = uniqid('export_');

        // 读取前端参数
        $fieldsStr = (string)$this->request->post('fields', '');
        $idsStr = (string)($params['ids'] ?? $this->request->post('ids', ''));

        if ($fieldsStr === '') {
            $this->error('请选择要导出的字段');
        }
        if ($idsStr === '') {
            $this->error('请选择要导出的数据');
        }

        // 规范化
        $fieldsStr = trim($fieldsStr, ", \t\n\r");
        $idsStr = trim($idsStr, ", \t\n\r");

        // 入库
        Db::name('export_tasks')->insert([
            'task_id' => $taskId,
            'user_id' => (int)$this->auth->id,
            'fields' => $fieldsStr,
            'ids' => $idsStr,
            'status' => 'pending',
            'progress' => 0,
            'createtime' => date('Y-m-d H:i:s')
        ]);

        // 立即返回JSON响应，避免后续再发送header（Linux下更严格）
        $resp = [
            'code' => 1,
            'msg' => '导出任务已提交',
            'time' => (string)time(),
            'data' => ['task_id' => $taskId]
        ];
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode($resp, JSON_UNESCAPED_UNICODE);

        if (function_exists('fastcgi_finish_request')) {
            // 结束HTTP响应，让客户端尽快拿到结果
            fastcgi_finish_request();
        } else {
            // 兼容环境：尽量把输出刷给客户端
            @ob_flush();
            @flush();
        }

        // 响应已结束：在后台继续处理任务（不要输出任何内容/不要发送header）
        ignore_user_abort(true);
        $this->processExportTaskBackground($taskId);
        exit;
    }

    /**
     * 查询导出状态
     */
    public function getExportStatus()
    {
        $taskId = $this->request->post('task_id');
        if (empty($taskId)) {
            $this->error('缺少任务ID');
        }
        
        $task = Db::name('export_tasks')->where('task_id', $taskId)->find();
        if (!$task) {
            $this->error('任务不存在');
        }
        
        $result = [
            'task_id' => $task['task_id'],
            'status' => $task['status'],
            'createtime' => $task['createtime']
        ];
        
        if ($task['status'] === 'completed') {
            // 构建完整的下载URL
            $request = Request::instance();
            $domain = $request->domain();
            $fileUrl = $task['file_url'] ?? '';
            
            if ($fileUrl) {
                if (strpos($fileUrl, 'http') !== 0) {
                    $result['download_url'] = $domain . $fileUrl;
                } else {
                    $result['download_url'] = $fileUrl;
                }
            } else {
                $result['download_url'] = '';
            }
            
            $result['completetime'] = $task['completetime'];
        } elseif ($task['status'] === 'failed') {
            $result['error_msg'] = $task['error_msg'];
        } elseif ($task['status'] === 'processing') {
            $result['progress'] = $task['progress'] ?? 0;
        }
        
        $this->success('查询成功', $result);
    }

    /**
     * 后台处理导出任务（真正的异步）
     */
    private function processExportTaskBackground($taskId)
    {
        // 更新状态为处理中
        Db::name('export_tasks')->where('task_id', $taskId)->update([
            'status' => 'processing',
            'progress' => 0
        ]);
        
        try {
            $task = Db::name('export_tasks')->where('task_id', $taskId)->find();
            // fields 为逗号字符串
            $fieldsStr = (string)$task['fields'];
            $fields = array_filter(array_map('trim', explode(',', $fieldsStr)));
            if (empty($fields)) {
                $fields = ['id','customer_id','amount','date'];
            }
            // 从任务读取 ids（逗号分隔或 JSON 兜底）
            $idsRaw = (string)($task['ids'] ?? '');
            $idsArr = [];
            if ($idsRaw !== '') {
                if (strpos($idsRaw, ',') !== false) {
                    $idsArr = array_filter(array_map('trim', explode(',', $idsRaw)));
                } else {
                    $decoded = json_decode($idsRaw, true);
                    if (is_array($decoded)) {
                        $idsArr = $decoded;
                    }
                }
            }
            if (empty($idsArr)) {
                throw new \Exception('未提供导出ID列表');
            }

            // 生成CSV文件（写头后流式写入每一批）
            $filename = '回款记录_' . date('YmdHis') . '.csv';
            $savePath = ROOT_PATH . 'public' . DS . 'uploads' . DS . 'excel';
            if (!is_dir($savePath)) {
                mkdir($savePath, 0755, true);
            }
            $filePath = $savePath . DS . $filename;
            $fp = fopen($filePath, 'w');
            fwrite($fp, "\xEF\xBB\xBF");
            $headers = $this->getExportHeaderTitles($fields);
            fputcsv($fp, $headers);

            $batchSize = 500;
            $total = count($idsArr);
            for ($i = 0; $i < $total; $i += $batchSize) {
                $batchIds = array_slice($idsArr, $i, $batchSize);
                $batchList = Db::name('payment_record a')
                    ->join('customer c', 'a.customer_id = c.id', 'LEFT')
                    ->join('user u', 'a.staff_id = u.id', 'LEFT')
                    ->join('contracts co', 'a.contract_id = co.id', 'LEFT')
                    ->join('payment_plan p', 'a.plan_id = p.id', 'LEFT')
                    ->join('account ac', 'a.account_id = ac.id', 'LEFT')
                    ->join('user ub', 'a.bill_staff_id = ub.id', 'LEFT')
                    ->field('a.*, c.customerName, c.uidipin, u.name as staffName, co.contractName, p.period, ac.account_name, ub.name as bill_staff_name')
                    ->whereIn('a.id', $batchIds)
                    ->order('a.id', 'asc')
                    ->select();

                if ($batchList) {
                    $this->streamCsvRows($fp, $batchList, $fields);
                }
                $progress = round((($i + count($batchIds)) / $total) * 100);
                Db::name('export_tasks')->where('task_id', $taskId)->update([
                    'progress' => min(100, $progress)
                ]);
                usleep(30000);
            }

            fclose($fp);

            // 更新任务状态
            $fileUrl = '/uploads/excel/' . $filename;
            Db::name('export_tasks')->where('task_id', $taskId)->update([
                'status' => 'completed',
                'file_url' => $fileUrl,
                'completetime' => date('Y-m-d H:i:s'),
                'progress' => 100
            ]);
            
        } catch (\Exception $e) {
            Db::name('export_tasks')->where('task_id', $taskId)->update([
                'status' => 'failed',
                'error_msg' => $e->getMessage()
            ]);
        }
    }

    // 生成表头标题
    private function getExportHeaderTitles($fields)
    {
        $fieldMap = [
            'customer_id' => '所属客户',
            'uidipin' => '客户UID/PIN',
            'lawyer' => '负责律师',
            'contract_id' => '所属合同',
            'code' => '回款编号',
            'loanno' => '贷款单号',
            'date' => '回款日期',
            'registrationDate' => '登记日期',
            'amount' => '回款金额',
            'method' => '回款方式',
            'payname' => '实际还款人',
            'plan_id' => '所属回款计划',
            'account_id' => '回款账户',
            'deduction_materials' => '京东材料截图',
            'remark' => '备注信息',
            'status' => '审核状态',
            'staff_id' => '负责人',
            'image' => '回款信息截图',
            'bill_staff_name' => '入账人',
            'billtime' => '入账时间',
            'department_id' => '部门',
            'createtime' => '创建时间',
            'updatetime' => '更新时间'
        ];
        $headers = [];
        foreach ($fields as $f) {
            $headers[] = $fieldMap[$f] ?? $f;
        }
        return $headers;
    }

    // 将一批数据写入CSV
    private function streamCsvRows($fp, $rows, $fields)
    {
        foreach ($rows as $item) {
            $csvRow = [];
            foreach ($fields as $f) {
                $csvRow[] = $this->formatFieldValue($f, $item);
            }
            fputcsv($fp, $csvRow);
        }
    }

    public function create()
    {
        $params = $this->request->post();

        // 验证必填字段
        if (empty($params['customer_id']) || empty($params['contract_id']) || empty($params['amount'])) {
            $this->error('缺少必填参数');
        }

        $plan_id=$params['planId'];
        $planModel=new \app\common\model\PaymentPlan();
        $plan=$planModel->find($plan_id);

        if($plan['status']=='已回款'){
            $this->error('该计划已回款');
        }
        if($plan['amount']!=$params['amount']){
            $this->error('还款金额与还款计划金额不一致');
        }
        // 处理日期格式
        $repaymentDate = !empty($params['repaymentDate']) ? date('Y-m-d', strtotime($params['repaymentDate'])) : date('Y-m-d');
        // 处理图片上传
        $images = [];
        if (!empty($params['screenshot']) && is_array($params['screenshot'])) {
            $images = $params['screenshot'];
        }

        if(!empty($params['profits'])){
            $profitids = implode(',', array_column($params['profits'], 'id'));
        }else{
            $profitids = '';
        }

        $deduction_materials = [];
        if (!empty($params['deduction_materials']) && is_array($params['deduction_materials'])) {
            $deduction_materials = $params['deduction_materials'];
        }
        $paymentRecord = new \app\common\model\PaymentRecord();
        $registrationDate = !empty($params['registrationDate']) ? date('Y-m-d', strtotime($params['registrationDate'])) : date('Y-m-d');
        // 保存回款记录
        $data = [
            'customer_id' => $params['customer_id'],
            'contract_id' => $params['contract_id'],
            'staff_id' => $this->auth->id,
            'amount' => $params['amount'],
            'method' => $params['method'] ?? '',
            'lawyer' => $params['lawyer'] ?? '',
            'date' => $repaymentDate,
            'createtime' => date('Y-m-d H:i:s'),
            'image' => !empty($images) ? json_encode($images) : null,
            'deduction_materials' => !empty($deduction_materials) ? json_encode($deduction_materials) : null,
            'remark' => $params['remark'] ?? '',
            'plan_id' => $plan_id,
            'payname' => $params['payer'] ?? '',
            'account_id' => $params['accountId'] ?? '',
            'code' => time(),
            'productName' => $params['productName'] ?? '',
            'registrationDate' => $registrationDate,
            'registration_date' => $registrationDate,
            'user_id' => $this->auth->id,
            'loanno' => $params['loanno'] ?? '',
            'profitids' => $profitids,
        ];
        $paymentRecord->save($data);


        //插入受益人

        if (!empty($params['profits']) && is_array($params['profits'])) {
            $now = date('Y-m-d H:i:s');
            $rows = [];
            foreach ($params['profits'] as $p) {
                if (isset($p['id'])) {
                    $rows[] = [
                        'payment_id' => $paymentRecord->id,
                        'profit_id'  => (int)$p['id'],
                        'createtime' => $now,
                    ];
                }
            }
            if (!empty($rows)) {
                Db::name('payment_profit')->insertAll($rows);
            }
        }


        $paymentPlanModel = new \app\common\model\PaymentPlan();
        $paymentPlanModel->where('id',$plan_id)->update(['status'=>'已回款']);

        $this->success('回款记录创建成功',[]);

    }

    /**
     * 处理删除功能
     * @param array $where 查询条件
     * @param array $params 请求参数
     * @return \think\response\Json
     */
    private function handleDelete($where, $params)
    {
        // 使用与列表相同的关联查询获取 a.id 列表
        $ids = Db::name('payment_record a')
            ->join('customer c', 'a.customer_id = c.id', 'LEFT')
            ->join('user u', 'a.staff_id = u.id', 'LEFT')
            ->join('user us', 'a.user_id = us.id', 'LEFT')
            ->join('contracts co', 'a.contract_id = co.id', 'LEFT')
            ->join('payment_plan p', 'a.plan_id = p.id', 'LEFT')
            ->join('account ac', 'a.account_id = ac.id', 'LEFT')
            ->where($where)
            ->column('a.id');

        if (empty($ids)) {
            $this->error('没有找到需要删除的记录');
        }

        // 检查是否有已入账的记录
        $billedRecords = Db::name('payment_record')
            ->where('id', 'in', $ids)
            ->where('is_bill', 1)
            ->where('is_delete', 0)
            ->select();
        
        if (!empty($billedRecords)) {
            $billedIds = array_column($billedRecords, 'id');
            $this->error('存在已入账记录，不能删除');
        }


            $planIds = Db::name('payment_record')
                ->where('id', 'in', $ids)
                ->where('is_delete', 0)
                ->column('plan_id');
            
            // 2. 软删除回款记录
            $result = Db::name('payment_record')
                ->where('id', 'in', $ids)
                ->update([
                    'is_delete' => 1,
                    'deletetime' => time(),
                ]);

            // 3. 将对应的还款计划状态更新为"待回款"
            if (!empty($planIds)) {
                Db::name('payment_plan')
                    ->where('id', 'in', $planIds)
                    ->update([
                        'status' => '待回款',
                        'updatetime' => date('Y-m-d H:i:s')
                    ]);
            }

        
        $deletedCount = $result ?: 0;
        $this->success("删除成功，共删除 {$deletedCount} 条记录");
       
    }

    public function deletepaymentrecord(){

        $ids = $this->request->post('ids', '');
        $ids=explode(',',$ids);
        
        if (empty($ids)) {
            $this->error('没有找到需要删除的记录');
        }

        // 检查是否有已入账的记录
        $billedRecords = Db::name('payment_record')
            ->where('id', 'in', $ids)
            ->where('is_bill', 1)
            ->where('is_delete', 0)
            ->select();
        
        if (!empty($billedRecords)) {
            $billedIds = array_column($billedRecords, 'id');
            $this->error('存在已入账记录，不能删除');
        }

            // 1. 获取要删除的回款记录对应的计划ID
            $planIds = Db::name('payment_record')
                ->where('id', 'in', $ids)
                ->where('is_delete', 0)
                ->column('plan_id');
            
            // 2. 软删除回款记录
            $PaymentrecordModel = new PaymentrecordModel();
            $result = $PaymentrecordModel->whereIn('id',$ids)->update(['is_delete'=>1,'deletetime'=>time()]);
            
            // 3. 将对应的还款计划状态更新为"待回款"
            if (!empty($planIds)) {
                Db::name('payment_plan')
                    ->where('id', 'in', $planIds)
                    ->update([
                        'status' => '待回款',
                        'updatetime' => date('Y-m-d H:i:s')
                    ]);
            }

         
            $this->success('删除成功');
            
      
    }

    public function processImport_old()
    {
        $fileUrl = $this->request->post('fileUrl');
        $sheetName = $this->request->post('sheetName');

        if (empty($fileUrl) || empty($sheetName)) {
            $this->error('文件URL和Sheet名称不能为空');
        }

        $localFilePath = ROOT_PATH . 'public' . str_replace('/', DS, $fileUrl);

        if (!file_exists($localFilePath)) {
            $this->error('服务器上找不到文件，请确认文件已正确上传路径：' . $localFilePath);
        }

        $importedCount = 0;
        $updatedCount = 0;
        $skippedCount = 0;
        $failedCount = 0;
        $errorMessages = [];


        $spreadsheet = IOFactory::load($localFilePath);
        $sheet = $spreadsheet->getSheetByName($sheetName);

        if (!$sheet) {
            $this->error('指定的Sheet名称不存在：' . $sheetName);
        }

        $highestRow = $sheet->getHighestRow();
        $highestColumn = $sheet->getHighestColumn(); // 比如 'BO'
        $maxColIndex = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestColumn);

        $header = [];
        for ($i = 1; $i <= $maxColIndex; $i++) {
            $header[] = trim($sheet->getCellByColumnAndRow($i, 1)->getValue());
        }

        $excelToDbMap = [
            '所属客户'   => 'customerName',
            '负责律师'   => 'lawyer',
            '所属合同'   => 'contractName',
            '回款编号'      => 'code', // 如有
            '贷款单号' => 'loanno',
            '回款日期'     => 'date',
            '登记日期'   => 'register_date',
            '回款金额'   => 'amount',
            '回款方式' => 'method',
            '实际还款人' => 'payname',
            '所属回款计划' => 'plan',
            '回款账户'         => 'account',
            '回款信息截图上传'         => 'image',
            '减免材料（京东专用）'         => 'deduction_materials',
            '备注信息'         => 'remark',

        ];
        // 缓存用户名称到ID的映射，避免循环查询
        $userCache = [];
        for ($rowNum = 2; $rowNum <= $highestRow; $rowNum++) {
            $rowData = [];
            for ($i = 1; $i <= $maxColIndex; $i++) {
                $headerIndex = $i - 1;
                if (!isset($header[$headerIndex])) continue;
                $headerName = $header[$headerIndex];
                $cellValue = $sheet->getCellByColumnAndRow($i, $rowNum)->getValue();
                if (isset($excelToDbMap[$headerName])) {
                    $dbField = $excelToDbMap[$headerName];
                    $rowData[$dbField] = trim($cellValue);
                }
            }


            if (isset($rowData['contractName'])) {
                $rowData['contract_id'] = Db::name('contracts')->where('contractName', $rowData['contractName'])->value('id');
                unset($rowData['contractName']);
            }

            if (isset($rowData['customerName'])) {
                $customer=Db::name('customer')->where('customerName', $rowData['customerName'])->find();
                if($customer){
                    $rowData['customer_id'] = $customer['id'];
                }else{
                    $failedCount++;
                    continue;
                }
                unset($rowData['customerName']);
            }

            if (isset($rowData['date'])) {
                if (is_numeric($rowData['date'])) {
                    $rowData['date'] = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($rowData['date'])->format('Y-m-d');
                }
            }

            if (isset($rowData['register_date'])) {
                if (is_numeric($rowData['register_date'])) {
                    $rowData['register_date'] = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($rowData['register_date'])->format('Y-m-d');
                }
            }

            if (isset($rowData['account'])) {
                $customer=Db::name('account')->where('account_name', $rowData['account'])->find();
                if($customer){
                    $rowData['account_id'] = $customer['id'];
                }else{
                    $failedCount++;
                    continue;
                }
                unset($rowData['account']);
            }

            $importedCount++;
            // 默认值
            $paymentrecordModel = new  PaymentrecordModel();

            $paymentrecordModel->save($rowData);
        }
        Db::name('import_log')->insert(
            [
                'success'=>$importedCount,
                'fail'=>$failedCount,
                'url'=>$fileUrl,
                'name'=>$sheetName,
                'total'=>$importedCount+$failedCount,
                'type'=>5,
                'user_id'=>$this->auth->id,
                'createtime'=>date('Y-m-d H:i:s'),
            ]
        );
        $this->success('导入完成', [
            'imported' => $importedCount,
            'updated' => $updatedCount,
            'skipped' => $skippedCount,
            'failed' => $failedCount,
            'errors' => $errorMessages,
            'total_rows' => $highestRow - 1, // 总行数（减去表头）
            'processed_rows' => $importedCount + $updatedCount + $skippedCount + $failedCount, // 处理的行数
            'batch_size' => 'all', // 一次性插入所有数据
            'performance' => [
                'total_time' => microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'],
                'rows_per_second' => ($importedCount + $updatedCount) / max(1, microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'])
            ]
        ]);

    }
    public function processImport()
    {
        $fileUrl = $this->request->post('fileUrl');
        $sheetName = $this->request->post('sheetName');
        $fieldMappings = $this->request->post('fieldMappings/a', []); // 前端传的映射关系
        $responsiblePersonType = $this->request->post('responsiblePersonType', 'excel'); // 负责人类型
        $responsibleUserId = $this->request->post('responsibleUserId', 0); // 指定负责人ID

        if (empty($fileUrl) || empty($sheetName) || empty($fieldMappings)) {
            $this->error('文件URL、Sheet名称和字段映射不能为空');
        }

        $localFilePath = ROOT_PATH . 'public' . str_replace('/', DS, $fileUrl);
        if (!file_exists($localFilePath)) {
            $this->error('服务器上找不到文件，请确认文件已正确上传路径：' . $localFilePath);
        }

        $importedCount = 0;
        $updatedCount = 0;
        $skippedCount = 0;
        $failedCount = 0;
        $errorMessages = [];

        $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($localFilePath);
        $sheet = $spreadsheet->getSheetByName($sheetName);
        if (!$sheet) {
            $this->error('指定的Sheet名称不存在：' . $sheetName);
        }

        $highestRow = $sheet->getHighestRow();
        $highestColumn = $sheet->getHighestColumn();
        $maxColIndex = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestColumn);

        // 1. 生成 Excel列名 => 列号 的映射
        $excelHeaderMap = [];
        for ($i = 1; $i <= $maxColIndex; $i++) {
            $headerName = trim($sheet->getCellByColumnAndRow($i, 1)->getValue());
            if ($headerName !== '') {
                $excelHeaderMap[$headerName] = $i;
            }
        }

        // 2. 生成 系统字段 => [excel列名, 默认值, 列号] 的映射
        $fieldMap = [];
        foreach ($fieldMappings as $map) {
            $sysField = $map['systemField'];
            $excelField = $map['excelField'];
            $defaultValue = $map['defaultValue'];
            $colIndex = isset($excelHeaderMap[$excelField]) ? $excelHeaderMap[$excelField] : null;
            $fieldMap[$sysField] = [
                'excelField' => $excelField,
                'defaultValue' => $defaultValue,
                'colIndex' => $colIndex
            ];
        }

        $customerModel = new CustomerModel();
        $contractsModel = new ContractsModel();
        $allData = []; // 用于批量插入的数据

        // 开启事务
        Db::startTrans();
        try {
            // 禁用自动提交以提高性能
            Db::execute('SET autocommit = 0');

            for ($rowNum = 2; $rowNum <= $highestRow; $rowNum++) { // 从第二行开始
                $rowData = [];
                $rowError = [];
                $plan_id = null;
                $contract_id = null;
                $import_amount = null;

                // 3. 按系统字段组装数据
                foreach ($fieldMap as $sysField => $info) {
                    $value = '';
                    if ($info['colIndex']) {
                        $cellValue = $sheet->getCellByColumnAndRow($info['colIndex'], $rowNum)->getValue();
                        $value = trim($cellValue);
                    }
                    if ($value === '' && $info['defaultValue'] !== '') {
                        $value = $info['defaultValue'];
                    }

                    // 特殊处理日期/时间字段
                    if ($value === '' || $value === null) {
                        $value = null; // 空值设为 null
                    } else {
                        if($sysField=='customer_id'){
                            $customer=$customerModel->where('customerName',$value)->where('is_delete',0)->find();
                            if($customer){
                                $value = $customer['id'];
                            }else{
                                $value = null; // 设置为 null，在外层统一处理
                            }
                        }

                        if($sysField=='plan_id'){
                            // Excel 传过来的 plan_id 实际上是期数 period
                            if(!empty($value) && !empty($contract_id)){
                                $plan = Db::name('payment_plan')
                                    ->where('contract_id', $contract_id)
                                    ->where('period', $value)
                                    ->where('is_delete', 0)
                                    ->find();
                                if($plan){
                                    $plan_id = $plan['id'];
                                    $rowData['plan_id'] = $plan['id']; // 更新为真正的 plan_id
                                }else{
                                    $plan_id = null;
                                }
                            }else{
                                $plan_id = null;
                            }
                        }

                        if($sysField=='contract_id'){
                            $contract=$contractsModel->where('contractName',$value)->where('is_delete',0)->find();
                            if($contract){
                                $value = $contract['id'];
                                $contract_id = $value;
                            }else{
                                $contract_id = null;
                            }
                        }

                        if($sysField=='staff_id'){
                            if($responsiblePersonType == 'excel'){
                                // 从Excel中获取负责人
                                $userModel=new User();
                                $user=$userModel->where('name',$value)->where('is_delete',0)->find();
                                if($user){
                                    $value = $user['id'];
                                }else{
                                    $value = null; // 设置为 null，在外层统一处理
                                }
                            }elseif($responsiblePersonType == 'assign'){
                                // 使用指定的负责人ID
                                $value = $responsibleUserId;
                            }else{
                                $value = null;
                            }
                        }

                        if($sysField=='amount'){
                            $import_amount = $value;
                        }
                    }
                    $rowData[$sysField] = $value;
                }

                // 验证 plan_id、contract_id、customer_id 和 staff_id 是否为空
                $validationErrors = [];
                if (empty($plan_id)) {
                    $validationErrors[] = "回款计划为空（请检查合同ID和期数是否正确，期数：" . ($rowData['plan_id'] ?? '空') . "）";
                }
                if (empty($contract_id)) {
                    $validationErrors[] = "合同为空";
                }
                if (empty($rowData['customer_id'])) {
                    $validationErrors[] = "客户为空";
                }
                if (empty($rowData['staff_id'])) {
                    $validationErrors[] = "负责人为空";
                }

                if (!empty($validationErrors)) {
                    $failedCount++;
                    $errorMessages[] = "第 {$rowNum} 行：" . implode('、', $validationErrors) . "，跳过此条数据";
                    continue;
                }

                // 验证金额是否匹配
                if ($import_amount !== null) {
                    $planModel = new PaymentPlanModel();
                    $plan = $planModel->where('id', $plan_id)
                        ->where('contract_id', $contract_id)
                        ->where('is_delete', 0)
                        ->find();

                    if (!$plan) {
                        $failedCount++;
                        $errorMessages[] = "第 {$rowNum} 行：找不到对应的还款计划";
                        continue;
                    }

                    if ($plan['amount'] != $import_amount) {
                        $failedCount++;
                        $errorMessages[] = "第 {$rowNum} 行：导入金额 {$import_amount} 与还款计划金额 {$plan['amount']} 不匹配";
                        continue;
                    }
                }

                // 通过 contract_id 和 period 检查重复
                if (!empty($rowData['contract_id']) && !empty($rowData['period'])) {
                    $existingPlan = Db::name('payment_plan')
                        ->where('contract_id', $rowData['contract_id'])
                        ->where('period', $rowData['period'])
                        ->where('is_delete', 0)
                        ->find();

                    if ($existingPlan) {
                        // 如果已存在相同的合同和期数，跳过或更新
                        $skippedCount++;
                        $errorMessages[] = "第 {$rowNum} 行：合同ID {$rowData['contract_id']} 的期数 {$rowData['period']} 已存在，跳过此条数据";
                        continue;
                    }
                }

                unset($rowData['uidipin']);
                if (empty($rowData) || !array_filter($rowData)) {
                    continue;
                }

                //创建人
                $rowData['user_id'] = $this->auth->id;

                $allData[] = $rowData;
            }

            // 一次性插入所有数据
            if (!empty($allData)) {
                try {
                    $res = Db::name('payment_record')->insertAll($allData);
                    if ($res !== false) {
                        $importedCount = count($allData);
                    } else {
                        $failedCount = count($allData);
                        $errorMessages[] = "批量插入失败：数据库操作失败";
                    }
                } catch (\Exception $e) {
                    $failedCount = count($allData);
                    $errorMessages[] = "批量插入失败：{$e->getMessage()}";
                }
            }

            // 提交事务
            Db::commit();

        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            $failedCount = $highestRow - 1; // 所有数据都失败
            $errorMessages[] = "导入过程中发生错误：{$e->getMessage()}";
        }

        Db::name('import_log')->insert([
            'success' => $importedCount,
            'fail' => $failedCount,
            'url' => $fileUrl,
            'name' => $sheetName,
            'type' => 5,
            'total' => $importedCount + $failedCount,
            'user_id' => $this->auth->id,
            'createtime' => date('Y-m-d H:i:s'),
        ]);

        $this->success('导入完成', [
            'imported' => $importedCount,
            'updated' => $updatedCount,
            'skipped' => $skippedCount,
            'failed' => $failedCount,
            'errors' => $errorMessages,
            'total_rows' => $highestRow - 1, // 总行数（减去表头）
            'processed_rows' => $importedCount + $updatedCount + $skippedCount + $failedCount, // 处理的行数
            'batch_size' => 'all', // 一次性插入所有数据
            'performance' => [
                'total_time' => microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'],
                'rows_per_second' => ($importedCount + $updatedCount) / max(1, microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'])
            ]
        ]);
    }
    public function getSelectPaymentRecord()
    {

        // 获取分页参数
        $page = $this->request->post('page', 1);
        $pageSize = $this->request->post('pageSize', 20);
        $customerId = $this->request->post('customerId');

        // 查询条件
        $where = [];
        $where['a.is_delete']=0;
        $where['a.customer_id']=$customerId;

        $list=Db::name('payment_record a')
            ->join('customer c', 'a.customer_id = c.id', 'LEFT')
            ->join('user u', 'a.staff_id = u.id', 'LEFT')
            ->join('contracts co', 'a.contract_id = co.id', 'LEFT')
            ->join('payment_plan p', 'a.plan_id = p.id', 'LEFT')
            ->field('a.*, c.id as customerID,c.customerName, c.uidipin,u.id as staff_id,u.name as staffName,co.id as contractId,co.contractName,p.period')
            ->where($where)
            ->order('a.id desc')
            ->page($page, $pageSize)
            ->select();

        $total =Db::name('payment_record a')
            ->join('customer c', 'a.customer_id = c.id', 'LEFT')
            ->join('user u', 'a.staff_id = u.id', 'LEFT')
            ->join('contracts co', 'a.contract_id = co.id', 'LEFT')
            ->join('payment_plan p', 'a.plan_id = p.id', 'LEFT')
            ->field('a.*, c.id as customerID,c.customerName, c.uidipin,u.id as staff_id,u.name as staffName,co.id as contractId,co.contractName,p.period')
            ->where($where)

            ->count();

        foreach ($list as $key=>$value){
            $customer=['id'=>$value['customerID'],'customerName'=>$value['customerName'],'uidipin'=>$value['uidipin']];
            $staff=['id'=>$value['staff_id'],'name'=>$value['staffName']];
            $contract=['id'=>$value['contractId'],'contractName'=>$value['contractName']];
            $plan=['id'=>$value['plan_id'],'period'=>$value['period']];
            $list[$key]['customer']=$customer;
            $list[$key]['staff']=$staff;
            $list[$key]['contract']=$contract;
            $list[$key]['plan']=$plan;
        }


        $total_amount_find=Db::name('payment_record a')
            ->join('customer c', 'a.customer_id = c.id', 'LEFT')
            ->join('user u', 'a.staff_id = u.id', 'LEFT')
            ->join('contracts co', 'a.contract_id = co.id', 'LEFT')
            ->join('payment_plan p', 'a.plan_id = p.id', 'LEFT')
            ->where($where)->field('sum(a.amount) as total')
            ->find();
        $total_amount=$total_amount_find['total']?$total_amount_find['total']:0;



        // 为图片URL添加域名前缀
        $request = Request::instance();
        $domain = $request->domain();
        foreach ($list as $k=>$v){
            if (!empty($v['image']) && is_string($v['image'])) {
                $certificate= json_decode($v['image'], true);
                foreach ($certificate as $key=>$value){
                    $certificate[$key]=$domain.$value;
                }
                $list[$k]['image'] = $certificate;
            }

        }


        $this->success('请求成功', ['list' => $list, 'total' => $total,'total_amount'=>$total_amount]);
    }


    public function importlog()
    {
        // 获取分页参数
        $page = $this->request->post('page', 1);
        $pageSize = $this->request->post('pageSize', 20);

        // 查询条件
        $where = [];
        $userId = $this->auth->id;
        $where['type']=5;
        $where['user_id']=$userId;

        $importlog = new \app\common\model\Importlog();
        $total = $importlog->where($where)->count();
        $list = $importlog
            ->with(['user' => function($query) {
                $query->field('id,name');
            }])
            ->where($where)
            ->order('id', 'desc')
            ->page($page, $pageSize)
            ->select();

        $request = \think\Request::instance();
        $domain = $request->domain();
        foreach ($list as $k => $v) {
            $list[$k]['url'] = $domain . $v['url'];
        }
        $this->success('请求成功', ['list' => $list, 'total' => $total]);
    }


    //入账
    public function enterBill(){
        $id = $this->request->post('id');
        $billtime=date('Y-m-d H:i:s');
        $bill_staff_id=$this->auth->id;

        Db::name('paymentRecord')->where('id',$id)->update(['is_bill'=>1,'bill_staff_id'=>$bill_staff_id,'billtime'=>$billtime]);
        $userinfo=$this->auth->getUserinfo();

        $data=[];
        $data['name']  =$userinfo['name'];
        $data['billtime']  =$billtime;
        $this->success('请求成功', $data);
    }

    /**
     * 向后兼容：旧前端仍调用 exportExcelAsync，仅使用 ids 和 fields
     */
    public function exportExcelAsync()
    {
        $fields = (string)$this->request->post('fields', '');
        $ids = (string)$this->request->post('ids', '');
        $params = ['fields' => $fields, 'ids' => $ids];
        return $this->exportAsync([], $params);
    }

    /**
     * 下载导出文件（独立下载接口，此处才设置下载header）
     */
    public function downloadExport()
    {
        $taskId = $this->request->get('task_id', $this->request->post('task_id', ''));
        if (empty($taskId)) {
            $this->error('缺少任务ID');
        }

        $task = Db::name('export_tasks')->where('task_id', $taskId)->find();
        if (!$task || $task['status'] !== 'completed' || empty($task['file_url'])) {
            $this->error('任务未完成或文件不存在');
        }

        $filePath = ROOT_PATH . 'public' . str_replace('/', DIRECTORY_SEPARATOR, $task['file_url']);
        if (!is_file($filePath)) {
            $this->error('文件不存在');
        }

        $fileName = basename($filePath);
        // 使用框架响应下载（此请求内才发送header）
        return Response::create($filePath, 'file')->download($fileName)->expire(3600);
    }

    /**
     * 字段值格式化（改为 protected 以避免回调上下文可见性问题）
     */
    protected function formatFieldValue($field, $item)
    {
        $value = $item[$field] ?? '';

        switch ($field) {
            case 'staff_id':
                return $item['staffName'] ?? '';
            case 'department_id':
                if ($item['staff_id']) {
                    $dept = Db::name('department')->where('id', $item['staff_id'])->value('title');
                    return $dept ?: '';
                }
                return '';
            case 'uidipin':
                return $item['uidipin'] ?? '';
            case 'account_id':
                return $item['account_name'] ?? '';
            case 'customer_id':
                return $item['customerName'] ?? '';
            case 'contract_id':
                return $item['contractName'] ?? '';
            case 'plan_id':
                return $item['period'] ?? '';
            case 'status':
                return $value == 1 ? '审核通过' : '待审核';
            case 'date':
            case 'registrationDate':
                return $value ? date('Y-m-d', strtotime($value)) : '';
            case 'createtime':
            case 'updatetime':
                return $value ? date('Y-m-d H:i:s', strtotime($value)) : '';
            case 'deduction_materials':
            case 'image':
                if (!empty($value) && is_string($value)) {
                    $images = json_decode($value, true);
                    if (is_array($images)) {
                        $imageNames = [];
                        foreach ($images as $imgPath) {
                            $imageNames[] = basename($imgPath);
                        }
                        return implode(', ', $imageNames);
                    }
                }
                return '';
            default:
                return $value;
        }
    }
}
